package com.github.gaojh.aop.interceptor;

import cn.hutool.core.collection.CollectionUtil;
import com.github.gaojh.aop.AopInfo;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author gaojh
 * @since 2020/3/30
 */
public class CglibInterceptor implements MethodInterceptor, Serializable {
    private final AopInfo aopInfo;

    public CglibInterceptor(AopInfo aopInfo) {
        this.aopInfo = aopInfo;
    }

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        if (!CollectionUtil.contains(aopInfo.getMethods(), method)) {
            return proxy.invokeSuper(obj, args);
        }

        Object result = null;
        // 开始前回调
        if (aopInfo.getAopAdapter().before(obj, method, args)) {
            try {
                result = proxy.invokeSuper(obj, args);
            } catch (InvocationTargetException e) {
                // 异常回调（只捕获业务代码导致的异常，而非反射导致的异常）
                if (aopInfo.getAopAdapter().afterException(obj, method, args, e.getTargetException())) {
                    throw e;
                }
            }
        }

        // 结束执行回调
        if (aopInfo.getAopAdapter().after(obj, method, args, result)) {
            return result;
        }
        return null;
    }
}
